const log4js      = require('../../utils/logUtils');
const logger      = log4js.getLogger('web');
const server      = require('../../sip/server/server');
const deviceCache = require("../../db/deviceCache");
const zlMediaKit  = require('../../service/ZlMediaKitApi');
const channelModel = require("../../model/channel");
const moment = require("moment");
const fileUtils = require("../../utils/fileUtils");
const hostModel = require("../../model/mediaServer");
const zlMediaKitUtil = require("../../service/ZlMediaKitUtils");
const sipUtils = require("../../utils/sipUtils");
const zlMediaKitApi = require("../../service/ZlMediaKitApi");
const config = require("../../db/config");

const TAG = "[ZlMediaKit Hook]";

//与 ZLMediaKit 交互
module.exports = {
    // ZLMediaKit 找不到流的时候请求这个接口
    onStreamNotFound(req,res){
        res.send({'code':0,'msg':'success'});
    },
    onFlowReport(req,res){
        res.send({'code':0,'msg':'success'});
    },
    onServerKeepAlive(req,res){
        // 更新媒体服务器的状态
        let serverId = req.body.mediaServerId;
        req.body.lastTime = new Date().getTime();
        if(!deviceCache.mediaServers[serverId]){deviceCache.mediaServers[serverId]={}}
        deviceCache.mediaServers[serverId] = Object.assign(deviceCache.mediaServers[serverId], req.body);
        res.send({'code':0,'msg':'success'});
    },
    onRtpServerTimeout(req,res){
        res.send({'code':0,'msg':'success'});
    },
    /**
     * zlMediaKit mp4 录制完成
     * @param req
     * @param res
     */
    onRecordMp4(req,res){
        const filePath = req.body.file_path;
        const fileSize = req.body.file_size;
        const folder = req.body.folder;
        const startTime = req.body.start_time;
        const timeLen = req.body.time_len;
        // 对文件进行改名，名称为 YYYY-MM-DD-HH-MM-SS_YYYY-MM-DD-HH-MM-SS
        const startMoment = moment(startTime*1000);
        const newName = folder + startMoment.format("YYYY-MM-DD") + "/" + startMoment.format('YYYYMMDD-HHmmss') + '_' + moment().format('YYYYMMDD-HHmmss') + '_' + parseInt(timeLen) + '_' + fileSize + '.mp4';
        logger.info(TAG, '[onRecordMp4] 录像,修改文件名',req.body.file_name, newName);
        fileUtils.rename(filePath, newName).then(() => {
            res.send({'code':0,'msg':'success'});
        }).catch(err => {
            logger.error(TAG, '[onRecordMp4] 改名失败', err);
            res.send({'code':1,'msg':'rename failure'});
        });
    },
    // ZLMediaKit 启动时调用这个接口
    onServerStarted(req,res){
        let serverId = req.body['general.mediaServerId'];
        deviceCache.mediaServers[serverId] = req.body;
        logger.info(TAG, '[onServerKeepAlive] 启动媒体服务器', serverId);
        req.body.startTime = new Date().getTime();
        res.send({'code':0, 'msg':'success'});
    },
    // 流没人观看时调用这个接口
    async onStreamNoneReader(req, res) {
        let stream = req.body.stream.split('-')[0].split('_');
        logger.info(TAG, '[onStreamNoneReader] param=', req.body, 'stream=', stream);
        if(req.body.app !== 'proxy') {
            await server.bye(stream[stream.length - 2], stream[stream.length - 1]);
        }
        res.send({'code': 0, 'msg': 'success'});
    },
    // 播放节目
    async onPlay(req,res){
        logger.info(TAG, '[onPlay] param=', req.body);
        let mediaServerId = req.body.mediaServerId;
        let stream_id = req.body.stream;
        const { deviceId, channelId, startTime, endTime } = sipUtils.parseStreamId(stream_id);
        const app = req.body.app;

        if(!mediaServerId || !stream_id){
            res.send({'code':1, 'msg':'param error','param': req.body});
            return;
        }
        let ret;
        if(app==='proxy'){
            // 请求拉流代理的通道，通过参数去获取拉流地址
            const findCamera = deviceCache.getCameraByChannelId(channelId);
            if(findCamera) {
                // 添加拉流代理
                await zlMediaKit.pull(app, stream_id, findCamera.mrl);
                ret = {'code': 0, 'msg': 'success'};
            }else{
                ret = {'code': 1, 'msg': '没有找到通道'};
            }
        }else {
            let s;
            if (app === 'rtp') {
                if (stream_id.indexOf('proxy') >= 0) {
                    // 远程录像的播放请求
                    s = 'Playback';
                } else {
                    // 直播
                    s='Play';
                }
                // GB28181的播放请求
                ret = await zlMediaKitUtil.play(stream_id, mediaServerId, deviceId, channelId, s, startTime, endTime);
            } else if (app === 'record') {
                s = 'Playback';
                // 本地录像的播放请求,使用拉流代理
                const physicPath = config.record.path + '/mp4/record/' + stream_id;
                await zlMediaKitApi.pullZlkFfmpeg(app, stream_id, physicPath);
                ret = {'code': 0, 'msg': 'success'};
            }
        }
        if(!ret){
            ret = {'code': 1, 'msg': '不支持的app'};
        }
        logger.info(TAG, '[onPlay] 返回值', ret);
        res.send(ret);
    },

    /**
     * 播放hls时鉴权，这里暂时全设置为允许观看
     */
    onHttpAccess(req,res){
        res.send({
            'code':0,
            'err':'',
            path:req.body.path,
            second:600,
            mediaServerId:req.body.mediaServerId
        });
    },
    async onStreamChanged(req,res){
        let method = req.body.regist;
        let serverId = req.body.mediaServerId;

        // logger.info(TAG,'onStreamChanged,请求参数:', req.body);
        if(method && req.body.schema==='rtsp'){
            // 注册时顺便截图
            let stream = req.body.stream.split('_');
            if(!stream || !stream[0] || !stream[1]){
                logger.warn(TAG,'截图，参数异常,stream=', stream);
                res.send({'code': 0, 'msg': 'success'});
                return;
            }else {
                const host = await hostModel.getInfoByServerId(serverId);
                let rtmp = channelModel.calcMediaUrl(host, stream[0], stream[1], 'rtmp_snap','rtp','');
                logger.info(TAG,'截图 mrl=', rtmp);

                zlMediaKit.snap(rtmp, stream[0], stream[1]).then((ret) => {
                    channelModel.updateSnap(ret.toString(), stream[0], stream[1]).then(() => {
                    }).catch(() => {
                        logger.error(TAG, '更新截图信息失败');
                    })

                }).catch((err) => {
                    logger.error(TAG,err);
                });
            }
        }
        res.send({'code': 0, 'msg': 'success'});
    },
    onPublish(req,res){
        res.send({'code': 0, 'msg': 'success'});
    }
};


